import Vue from 'vue'
import VueRouter from 'vue-router'
// import Films from '../views/Films.vue'
// import Cinemas from '../views/Cinemas.vue'
// import City from '../views/City.vue'
// import Search from '../views/Search.vue'
// import Center from '../views/Center.vue'
// import Detail from '../views/Detail.vue'
// import Login from '../views/Login.vue'
// import Order from '../views/Order.vue'
// import Nowplaying from '../views/Films/NowPlaying.vue'
// import Comingsoon from '../views/Films/ComingSoon.vue'
// import NotFound from '../views/404.vue'

// 注册路由
Vue.use(VueRouter)

const routes = [
  {
    // 如果path为'/'的时候可以省略
    path: '',
    // 重定向
    redirect: '/films'
  },
  {
    // 注意，路由不可省略第一个'/'否则匹配不上，不想fetch和
    path: '/films',
    // component: Films,
    // 路由（组件）的懒加载
    component: () => import('../views/Films.vue'),
    // 孩子(嵌套)路由, 二级路由/孩子(嵌套)路由不可省略/films就是父路由的路径
    children: [
      {
        path: '/films/nowPlaying',
        // component: NowPlaying,
        component: () => import('../views/Films/NowPlaying.vue')
      },
      {
        path: '/films/comingsoon',
        // component: Comingsoon,
        component: () => import('../views/Films/ComingSoon.vue')
      },
      // 子路由重定向, 每次路由为films重定向'/films/nowPlaying'
      {
        path: '/films',
        redirect: '/films/nowPlaying'
      }
    ]
  },
  // 动态路由----就是路径url传参改造的(跟nodejs一样), 格式一样的---/:param
  {
    // 命名路由: 给路由起一个别名
    name: 'fqmyysjjd',
    path: '/detail/:id',
    // component: Detail,
    component: () => import('../views/Detail.vue')
  },
  {
    path: '/cinemas',
    // component: Cinemas,
    component: () => import('../views/Cinemas.vue')
  },
  {
    path: '/city',
    // component: City,
    component: () => import('../views/City.vue')
  },
  {
    path: '/cinemas/search',
    // component: Search,
    component: () => import('../views/Search.vue')
  },
  {
    path: '/center',
    // component: Center,
    component: () => import('../views/Center.vue'),
    // meta正常为空，我们可以在里面自定义属性，在组件里使用this.$route  和  路由拦截的时候的to/from  对象都可以访问meta里的属性
    meta: {
      requireVerifide: true
    }

    // 局部路由拦截: 路由内
    // beforeEnter: intercept  //方法定义在最后,就是跟全局拦截的方法一模一样没有区别,只不过换了位置而已
  },
  {
    path: '/consult',
    // component: Order,
    component: () => import('../views/Consult.vue'),
    meta: {
      requireVerifide: true
    }
    // beforeEnter: intercept
  },
  {
    path: '/login',
    // component: Login,
    component: () => import('../views/Login.vue')
  },
  {
    path: '*',
    // component: NotFound,
    component: () => import('../views/404.vue')
  }

]

// 就是把一个对象作为VueRouter的构造函数的参数，创建VueRouter实例导出，就是路由
// routes就是保存的路径和对应的路由，内部VueRouter会做一些事情，让我们只要访问对应路径就会插入对应组件，
// 如果显示的组件(一般根组件)留了对应的router-view/link  插槽封装，就会插入该组件
// 如果走完路由都没有匹配到，那么就不会有组件插入，所以路由最后一般写一个*表示都没匹配就走*写404
// 配置了路由后，在路由的域名后会有/#/的标志

const router = new VueRouter({
  mode: 'history', // history模式指的就是消除#的模式，更贴近于后端路由的写法，就像发送页面请求的一样， history更好看
  // mode: 'hash',       //hash模式就是带#的模式，看见hash模式表示一定是前端路由
  // mode: 'abstract'    //这个模式路由不变，永远一个url
  routes
  // routes: routes
})

// 全局拦截(守卫)  , next跟nodejs的不一样，内部可以传参对象或者就是path代表跳转到对应的路由对象或者路由路径
router.beforeEach((to, from, next) => {
  // console.log(to)    // 将要达到的路由
  // console.log(from)  // 由哪里跳转

  // 这里写if 或者用switch很麻烦而且低级，如果需要很多个路由匹配都要校验呢, 那得多长的代码，看下面的解决方案
  // if(to.path === '/center'){

  // 高级用法：利用在meta里能够自定义的属性，可以对需要登录校验的对应路由设置属性为true没有设置的就是undefine就是false，
  // 直接一个判断即可
  // console.log(to.meta.requireVerifide)
  if (to.meta.requireVerifide) {
    // 模拟取token发送到后端校验
    console.log(localStorage.getItem('token'))
    console.log(typeof localStorage.getItem('token'))
    if (localStorage.getItem('token')) {
      next()
    } else {
      // 给next传递一个url路径--路由路径
      // next('/login')
      // 传递对象，可以设置path, query等，query就是跟get请求传参一样，此时传递的属性是redirect，值：跳转登录前的一个路由的路径
      // 传递这个值是为了实现登陆后直接跳转到之前没有登录或者登录过期的页面（保存到query传到login路由的的路径里），
      // 在login登陆成功,直接this.$route.query取对应的参数再直接跳转回去回去
      next({
        path: '/login',
        query: {
          redirect: to.fullPath // 写fullPath为了完整的url保持向PageNum这样的参数也能生效,如果登陆成功,直接跳转想要到达的页面
        }
      })
    }
  } else {
    next()
  }

  // 逻辑：token为例
  // 只有登录了，去后端校验，成功就生成token存在本地，给成功的相应，如果没有就给失败的相应相应
  // 每次对路由全局拦截，对于需要登录才能查看的信息，直接跳转到登录界面next('/login)，对于不需要登录的则next()
  // 具体拦截这么判断token对不对？npm下载jwt， 里面应该是有对应的解码和加密方法，直接取本地token加密后（）一层保护，
  // 传到后端解码，看解码的用户名密码是否匹配，如果匹配不过期就给成功相应，否则失败
  // token为空直接把跳转到login就行了
})
// 我在相应的组件内配置局部拦截和路由对象传入的数组元素内部配置局部拦截和在全局配置拦截是一样的效果

// 全局后置钩子
router.afterEach((to, from) => {
  // 没有next参数,此时已经跳转,
  // 跳转后对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
})

function intercept (to, from, next) {
  if (to.meta.requireVerifide) {
    // 模拟取token发送到后端校验
    console.log(localStorage.getItem('token'))
    console.log(typeof localStorage.getItem('token'))
    // 加密
    if (localStorage.getItem('token')) {
      next()
    } else {
      // 给next传递一个url路径--路由路径
      // next('/login')
      // 传递对象，可以设置path, query等，query就是跟get请求传参一样，此时传递的属性是redirect，值：跳转登录前的一个路由的路径
      // 传递这个值是为了实现登陆后直接跳转到之前没有登录或者登录过期的页面（保存到query传到login路由的的路径里），
      // 在login登陆成功,直接this.$route.query取对应的参数再直接跳转回去回去
      next({
        path: '/login',
        query: {
          redirect: to.fullPath // 写fullPath为了完整的url保持向PageNum这样的参数也能生效,如果登陆失效,直接跳转原来的第几页
        }
      })
    }
  } else {
    next()
  }
}

export default router
